package com.zp.manager.uploadtemplate;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import com.zp.enums.ErrorCode;
import com.zp.exception.BusinessException;
import com.zp.utils.ThrowUtils;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Set;

/**
 * URL 上传文件
 */
@Service
public class URLPictureUpload extends PictureUploadTemplate {
    /**
     * 校验 URL
     *
     * @param t   URL
     * @param <T> URL
     */
    @Override
    protected <T> void validPicture(T t) {
        // 强转为 String
        String fileUrl = (String) t;
        if (StrUtil.isEmpty(fileUrl)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件不能为空");
        }
        // 1. 验证 URL 的格式
        try {
            new URL(fileUrl);
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件格式错误");
        }
        // 2. 验证 URL 协议
        if (!fileUrl.startsWith("http://") && !fileUrl.startsWith("https://")) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件格式错误");
        }
        // 3. 验证 URL 是否存在(HEAD 请求)
        try (HttpResponse response = HttpUtil.createRequest(Method.HEAD, fileUrl).execute()) {
            // 浏览器可能不支持 HEAD 请求
            if (response.getStatus() != HttpStatus.HTTP_OK) {
                return;
            }
            // 验证文件类型, 请求的与实体对应的 MIME 信息
            String contentType = response.header("Content-Type");
            if (StrUtil.isNotBlank(contentType)) {
                // 允许上传的图片类型
                final Set<String> ALLOWED_CONTENT_TYPE = Set.of("image/jpeg", "image/png", "image/webp", "image/jpg");
                ThrowUtils.throwIf(!ALLOWED_CONTENT_TYPE.contains(contentType.toLowerCase()), ErrorCode.PARAMS_ERROR, "文件格式错误");
            }
            // 验证图片大小
            String contentLength = response.header("Content-Length");
            if (StrUtil.isNotBlank(contentLength)) {
                long allowedLength = Long.parseLong(contentLength);
                final long MAX_SIZE = 1024 * 1024 * 8;
                ThrowUtils.throwIf(allowedLength > MAX_SIZE, ErrorCode.PARAMS_ERROR, "文件大小不能超过 8 MB");
            }
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }
    }

    /**
     * 获取源文件名
     *
     * @param t   源文件: URL
     * @param <T> URL
     * @return 原始文件名
     */
    @Override
    protected <T> String getOriginalFilename(T t) {
        // 强转为 String
        String fileUrl = (String) t;
        // 获取文件名
        return FileUtil.getName(fileUrl) + "." + FileUtil.extName(fileUrl);
    }

    /**
     * 处理文件: 下载文件
     *
     * @param t    URL
     * @param file 文件
     * @param <T>  URL
     * @throws IOException IO异常
     */
    @Override
    protected <T> void processFile(T t, File file) throws IOException {
        // 强转为 String
        String fileUrl = (String) t;
        HttpUtil.downloadFile(fileUrl, file);

    }
}
